home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / mhctl / mhctl.c < prev   
C/C++ Source or Header  |  1993-01-08  |  4KB  |  125 lines

  1. //
  2. // GetMenuHctl
  3. //
  4. // this code demonstrates, how one can get a menu's control handle in a
  5. // custom control for VB2. It can be used e.g. during the processing
  6. // of WM_MENUSELECT to get the tag property of a menu entry.
  7. //
  8. // the code is taken (with some modifications) from the last version of my
  9. // status bar control, where it is used to fire the SelectedTag event.
  10. // I will upload the control within the next days.
  11. //
  12. // Input:      HWND hWndForm            window handle of the form
  13. //             WORD wp                  see SDK documentation for WM_MENUSELECT
  14. //             LONG lp                  ...
  15. //
  16. // Return:     hctlMenu                 control handle (or NULL)
  17. //
  18. // THIS CODE USES UNDOCUMENTED FEATURES OF VB2, AND THERE WILL BE CHANGES
  19. // NEEDED FOR FUTURE VERSIONS. WE ALL SHOULD HOPE, THAT MS WILL MAKE THE
  20. // CONTROL HANDLE OF MENU ITEMS AVAILABLE WITH AN API CALL.
  21. //
  22. // I had a similar routine working for VB1 (see version 1.x of StBar), but 
  23. // it could not be ported to VB2, becaused it depended on assumptions on
  24. // the messages, message ordering, and menu item ids.
  25. //
  26. // Any comment to this is welcome
  27. // 
  28. // Bernd Beekes, 100031,2063
  29. // 
  30.  
  31. #include <windows.h>
  32. #include <vbapi.h>
  33.  
  34. #define MENU_OFFSET             7
  35. #define ITEM_OFFSET             8
  36. #define MENU_CONTROL           "MENU"
  37.  
  38. HCTL NEAR GetMenuHctl(HWND hWndForm, WORD wp, LONG lp)
  39.  
  40. {
  41.     HMENU       hMenu;
  42.     SHORT       fwMenu;
  43.     HCTL        hctl;
  44.     HCTL        hctlMenu;
  45.     SHORT       nMinItem;
  46.     WORD        nItem;
  47.     LPMODEL     lpModel;
  48.     LPSHORT     lpMenuStruct;
  49.     LPSTR       lpszName;
  50.     
  51.     // get menu handle and flags
  52.       
  53.     fwMenu = LOWORD(lp);
  54.     hMenu  = (HMENU) HIWORD(lp);
  55.             
  56.     // ignore menu closing, separators, system menu, ...
  57.             
  58.     if (hMenu == 0)
  59.         return NULL;
  60.                                
  61.     if (fwMenu & MF_SEPARATOR)
  62.         return NULL;
  63.  
  64.     if (fwMenu & MF_SYSMENU)
  65.         return NULL;
  66.         
  67.     // determine menu handle and item number
  68.     
  69.     if (fwMenu & MF_POPUP)
  70.     {
  71.         hMenu = (HMENU) wp;
  72.         nItem = 0;
  73.     }
  74.     else
  75.     {
  76.         nItem = wp;
  77.     }
  78.     
  79.     // initialize variables and walk thru control collection
  80.  
  81.     nMinItem = -1;
  82.     hctlMenu = NULL;
  83.     
  84.     hctl     = VBGetHwndControl(hWndForm);
  85.     hctl     = VBGetControl(hctl, GC_CHILD);
  86.     hctl     = VBGetControl(hctl, GC_FIRSTCONTROL);
  87.     
  88.     while (hctl != NULL)
  89.     {
  90.         lpModel  = VBGetControlModel(hctl);
  91.         lpszName = (LPSTR) MAKELONG(lpModel->npszClassName, (_segment) lpModel);
  92.  
  93.         if (lstrcmpi(lpszName, MENU_CONTROL) == 0)
  94.         {
  95.             lpMenuStruct = (LPSHORT) VBDerefControl(hctl);
  96.             
  97.             if ((HMENU) *(lpMenuStruct + MENU_OFFSET) == hMenu)
  98.             {
  99.                 // for menu items the item id is at lpMenuStruct + ITEM_OFFSET
  100.                 
  101.                 if (nItem != 0 && (WORD) *(lpMenuStruct + ITEM_OFFSET) == nItem)
  102.                 {
  103.                     hctlMenu = hctl;
  104.                     break;
  105.                 }
  106.                 
  107.                 // for pop up entries, look for the entry with minimal id !!!
  108.                 
  109.                 if (nItem == 0)
  110.                 {
  111.                     if (nMinItem == -1 || nMinItem > *(lpMenuStruct + ITEM_OFFSET))
  112.                     {
  113.                         nMinItem = *(lpMenuStruct + ITEM_OFFSET);
  114.                         hctlMenu = hctl;
  115.                     }
  116.                 }
  117.             }
  118.         }
  119.         
  120.         hctl = VBGetControl(hctl, GC_NEXTCONTROL);
  121.     }
  122.  
  123.     return  hctlMenu;
  124. }
  125.